﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.ComponentModel;
using System.Collections.Generic;
using Tedds_Tool;
using Tedds_Tool.Automatables;
using StandardScriptItems;
using CommonInterfaces.Models;

namespace GUI.Custom_Classes
{
    public partial class ScriptBuilder : ListBoxItem, IScriptBuilder, INotifyPropertyChanged
    {
        public UIElement child;
        IScriptItemFactory factory;
        
        //Added default constructor to enable referencing for new xaml windows (Create Precondition, Create Action...)
        public ScriptBuilder()
        {
            InitializeComponent();
        }

        public ScriptBuilder(IScriptItemFactory factory, String forCommand) : this()
        {
            this.factory = factory;
            List<String> commands = factory.CommandsFor(forCommand);
            System.Collections.Generic.SortedSet<String> s = new System.Collections.Generic.SortedSet<String>(commands);

            //commands.RemoveAll(delegate(string str) { return true; });
            //commands.Sort();
                
            
            foreach (String cmd in s)
            {
                ComboBoxItem item = new ComboBoxItem();
                item.Name = cmd;
                item.Content = cmd;
                Command_Box.Items.Add(item);
            }
        }

        public String Text
        {
            get
            {
                return this.ToString();
            }
        } 

        /// <summary>
        /// Method to initialize current automation elements for all ScriptBuilder
        /// objects.
        /// </summary>
        /// <param name="n">Initializing string for scriptbuilder.</param>
        /// <param name="m">Valid automation elements for the current target.</param>
        public void references(string n)
        {
            if (!String.IsNullOrWhiteSpace(n))
                this.Name = "ScriptBuilder_" + n;
            else
                this.Name = "Default ScriptBuilder";

            child = null;
        }

        private void Command_Box_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.CommandBox.Items.Count >= 1 && "--Select a command--".Equals( (this.CommandBox.Items[0] as ComboBoxItem).Content ))
                this.CommandBox.Items.RemoveAt(0);
            
            if (e.RemovedItems.Count == 0 || e.AddedItems.Count == 0)
                return;

            string newSelection = (e.AddedItems[0] as ComboBoxItem).Content.ToString().Trim();

            if (child != null && newSelection.Equals(child.ToString().Split('|')[0]))
                return;

            Griddy.Children.Remove(child);
            child = null;

            UIElement temp;

            temp = factory.CreateScriptItem(newSelection, NotifyTextChanged);
            Grid.SetColumn(temp, 1);
            Griddy.Children.Add(temp);
            child = temp;
            
            NotifyTextChanged();
        }

        /// <summary>
        /// Returns the TTL version of the ScriptBuilder.
        /// </summary>
        public override string ToString()
        {
            string ret = string.Empty;
            object obj = Dispatcher.Invoke(new StrDelegate(delegate()
            {
                return child == null ? "" : child.ToString();
            }));
            ret = (CommandBox.SelectedItem as ComboBoxItem).Content.ToString() + " | " + (obj as String);
            return ret;
        }

        private delegate String StrDelegate();

        #region Automation

        protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
        {
            return new ScriptBuilder_AutomationPeer(this);
        }

        public class ScriptBuilder_AutomationPeer : FrameworkElementAutomationPeer, IValueProvider, ISelectionItemProvider
        {
            ScriptBuilder host;

            public ScriptBuilder_AutomationPeer(ScriptBuilder rb)
                : base(rb)
            {
                host = rb;
            }

            #region FrameworkElementAutomationPeer

            public override Object GetPattern(PatternInterface patternInterface)
            {
                if (patternInterface.Equals(System.Windows.Automation.Peers.PatternInterface.Value))
                    return this;
                if (patternInterface.Equals(System.Windows.Automation.Peers.PatternInterface.SelectionItem))
                    return this;
                return base.GetPattern(patternInterface);
            }

            protected override string GetClassNameCore()
            {
                return "ScriptBuilder";
            }

            protected override string GetAutomationIdCore()
            {
                return host.Name;
            }

            protected override string GetNameCore()
            {
                return host.Name;
            }

            protected override AutomationControlType GetAutomationControlTypeCore()
            {
                return AutomationControlType.Custom;
            }

            #endregion

            #region IValueProvider Members

            bool IValueProvider.IsReadOnly
            {
                get { return false; }
            }

            void IValueProvider.SetValue(string value)
            {

            }

            string IValueProvider.Value
            {
                get
                {
                    return host.ToString();
                }
            }
            #endregion

            #region ISelectionItemProvider Members

            public void AddToSelection()
            {
                host.IsSelected = true;
            }

            public bool IsSelected
            {
                get { return host.IsSelected; }
            }

            public void RemoveFromSelection()
            {
                host.IsSelected = false;
            }

            public void Select()
            {
                host.IsSelected = true;
            }

            public IRawElementProviderSimple SelectionContainer
            {
                get { return (host.Parent as IRawElementProviderSimple); }
            }

            #endregion
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        
        /// <summary>
        /// Updates the ObservableList that something has changed with this ScriptBuilder.
        /// </summary>
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        /// <summary>
        /// This will get made into a delegate and passed to children so that 
        /// they can invoke the above method seamlessly.
        /// </summary>
        protected void NotifyTextChanged() 
        {
            NotifyPropertyChanged("Text");
        }

        #endregion

        public ComboBox CommandBox
        {
            get { return Command_Box; }
        }

        public void AddLeftDownEvent(System.Windows.Input.MouseButtonEventHandler mouseButtonEventHandler)
        {
            MouseLeftButtonDown += mouseButtonEventHandler;
        }

        public void Filter(LEET.CommonInterfaces.Filter<string> test)
        {
            for (int i = 0; i < CommandBox.Items.Count; i++ )
                if(!test((CommandBox.Items[i] as ComboBoxItem).Content as String))
                    Command_Box.Items.RemoveAt(i--);
        }
    }
}
